import math
from datetime import datetime, timedelta
# [1d,2d,4d,7d,15,30d,...]
class EbbinghausReviewScheduler:
    def __init__(self, initial_interval_days=1, gamma=2.0, fail_penalty=0.6, min_interval=1):
        """
        初始化复习调度器
        
        参数:
            initial_interval_days: 初始复习间隔(天)
            gamma: 成功回忆时的间隔扩展因子(默认2.0)
            fail_penalty: 失败回忆时的间隔惩罚系数(默认0.6)
            min_interval: 最小允许间隔(天)
        """
        self.gamma = gamma
        self.fail_penalty = fail_penalty
        self.min_interval = min_interval
        self.current_interval = initial_interval_days
        self.last_review_date = None
        
    def calculate_retention(self, t, difficulty_S=10):
        """计算t天后的记忆保留率(0-1范围)"""
        return math.exp(-t / difficulty_S)
    
    def next_review_interval(self, recall_success):
        """
        计算下次复习间隔
        
        参数:
            recall_success: bool, 本次是否成功回忆
        返回:
            下次复习间隔(天)
        """
        if recall_success:
            # 成功回忆则扩展间隔
            new_interval = self.current_interval * self.gamma
        else:
            # 失败回忆则缩短间隔
            new_interval = max(
                self.current_interval * self.fail_penalty,
                self.min_interval
            )
        
        self.current_interval = new_interval
        return new_interval
    
    def schedule_next_review(self, recall_success):
        """
        安排下次复习日期
        
        参数:
            recall_success: bool, 本次是否成功回忆
        返回:
            (下次复习日期datetime, 间隔天数)
        """
        interval = self.next_review_interval(recall_success)
        
        if self.last_review_date is None:
            next_date = datetime.now() + timedelta(days=interval)
        else:
            next_date = self.last_review_date + timedelta(days=interval)
            
        self.last_review_date = next_date
        return next_date, interval

# # 使用示例
# if __name__ == "__main__":
#     scheduler = EbbinghausReviewScheduler(initial_interval_days=1)
    
#     # 模拟5次复习过程
#     test_results = [True, True, False, True, True]  # 第3次复习失败
    
#     print("模拟动态复习计划:")
#     print("="*40)
#     for i, success in enumerate(test_results):
#         next_date, interval = scheduler.schedule_next_review(success)
#         retention = scheduler.calculate_retention(interval) * 100
        
#         print(f"第{i+1}次复习: {'成功' if success else '失败'}")
#         print(f"下次间隔: {interval:.1f}天后 (预测保留率: {retention:.1f}%)")
#         print(f"建议日期: {next_date.strftime('%Y-%m-%d')}")
#         print("-"*30)
